package projectisd.client;

import java.util.List;
import java.util.Date;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.google.gwt.user.datepicker.client.DatePicker;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
/** 
 * In deze klas wordt de interface aangeroepen om een Inschrijving op een vak te kunnen toevoegen
 * in de webbrowse
 * @author Team 2
 * @version 7.0
 */
public class InschrijvenVakGUI {
	/* Constants. */
	private static final String LISTING_ROOT_PANEL = "guiListing";
	private static final String FORM_ROOT_PANEL = "guiForm";
	private static final String STATUS_ROOT_PANEL = "guiStatus";
	private static final String TOOL_BAR_ROOT_PANEL = "guiToolBar";
	private static final int EDIT_LINK = 5;
	private static final int REMOVE_LINK = 6;

	/* GUI Widgets */
	protected Button addButton;
	protected Button updateButton;
	protected Button addNewButton;
	protected ListBox vakNrField;
	protected TextBox studentNummerField;
	protected Label titel;
	protected Label status;
	protected Grid listGrid;
	protected Grid formGrid;
	protected Image hulogo;

	/* Data model */
	private List<Vak> vakken;

	private List<InschrijvenVak> inschrijvenVakken;
	private InschrijvenVak currentInschrijvenVak;
	protected InschrijvenVakDelegate inschrijvenVakService;
	
	/** 
	 * In deze methode worden alle Widgets gemaakt die later weer kunnen worden opgehaald
	 */
	
	public void init() {
		addButton = new Button("Inschrijven Vak");
		addNewButton = new Button("Inschrijven new Vak");
		updateButton = new Button("Update inschrijving");
		vakNrField = new ListBox();
		studentNummerField = new TextBox();
		status = new Label();
		listGrid = new Grid(2,7);


		hulogo = new Image("http://jansen-schoonhoven.com/Downloads/hulogo.jpg");

		titel = new Label("Inschrijven Vak");

		buildForm();
		placeWidgets();
	}
	
	/** 
	 * Hier in worden de widgets gebruikt in de Buildform waar in een grid wordt gebruikt
	 * om de widgets te plaatsen op het scherm
	 */
	
	private void buildForm() {
		formGrid = new Grid(5,3);
		formGrid.setVisible(false);

		formGrid.setWidget(0, 0, titel);
		formGrid.setWidget(0, 2, hulogo);

		formGrid.setWidget(1, 0, new Label("Studentnummer"));
		formGrid.setWidget(1, 1, studentNummerField);

		formGrid.setWidget(2, 0, new Label("Cursus Code"));
		formGrid.setWidget(2, 1, vakNrField);

		formGrid.setWidget(3, 0, updateButton);
		formGrid.setWidget(3, 1, addButton);

	}
	
	/** 
	 * Hier in worden de widgets zoals listgrid formgrid en status geplaats in
	 * de rootpanel 
	 */

	private void placeWidgets() {
		RootPanel.get(LISTING_ROOT_PANEL).add(listGrid);
		RootPanel.get(FORM_ROOT_PANEL).add(formGrid);
		RootPanel.get(STATUS_ROOT_PANEL).add(status);
		RootPanel.get(TOOL_BAR_ROOT_PANEL).add(addNewButton);
	}
	
	/** 
	 * In deze methode wordt uitgevoerd om bepaalde widgets te kunnen hiden als deze wordt aangeroepen
	 */

	public void hideGui() {
		formGrid.setVisible(false);
		listGrid.setVisible(false);
		status.setVisible(false);
		addNewButton.setVisible(false);
	}
	
	/** 
	 * In deze methode wordt het formulier aangeroepen wat de gebruiker
	 * kan invullen	
	 */

	private void loadForm(InschrijvenVak inschrijvenVak) {
		this.formGrid.setVisible(true);
		currentInschrijvenVak = inschrijvenVak;

		this.vakNrField.clear();
		int index = 0;
		int selected = 0;
		for (Vak vak : vakken) {
			this.vakNrField.addItem(vak.getCode());
			if (inschrijvenVak.getVakNr().longValue() == 
				vak.getVakNr().longValue()) {
				selected = index;
			}
			index++;
		}        
		this.studentNummerField.setText(inschrijvenVak.getStudentnummer());
		this.vakNrField.setSelectedIndex(selected);
	}
	
	/** 
	 * In deze methode wordt een Vak opgeslagen in de database
	 * 
	 */


	private void copyFieldDateToInschrijvenVak() {

		int selected = this.vakNrField.getSelectedIndex();

		Long vakNr = 0L;
		if (vakken.size() > selected) {
			vakNr = vakken.get(selected).getVakNr();
		}
		currentInschrijvenVak.setStudentnummer(studentNummerField.getText());
		currentInschrijvenVak.setVakNr(vakNr);
	}
	
	/** 
	 * In deze methode wordt verteld wanneer bepaalde knoppen 
	 * zichtbaar mogen zijn zodra er een bepaalde knop wordt geselecteerd
	 * 
	 */

	public void gui_eventListGridClicked(Cell cellClicked) {
		int row = cellClicked.getRowIndex();
		int col = cellClicked.getCellIndex();

		InschrijvenVak inschrijvenVak = this.inschrijvenVakken.get(row);
		//this.status.setText("VakNr was " + inschrijvenVak.getVakNr() + " clicked ");

		if (col==EDIT_LINK) {
			this.addNewButton.setVisible(false);
			this.updateButton.setVisible(true);
			this.addButton.setVisible(false);
			loadForm(inschrijvenVak);
		} else if (col==REMOVE_LINK) {
			if (Window.confirm("Inschrijving verwijderen?")) {
				this.inschrijvenVakService.removeInschrijvenVak(inschrijvenVak);
			}
		}
	}
	
	/** 
	 * In deze methode staat wat er moet gebeuren voordat op Addbutton wordt
	 * geclickt voordat de ingevulde gegevens worden opgeslagen.
	 */


	public void gui_eventAddButtonClicked() {
		if	(studentNummerField.getText().length() == 0)
		{	Window.alert("Alle velden moeten gevuld zijn");
		}  else if (!studentNummerField.getText().matches("^[0-9]+$"))
		{	Window.alert("Studentnumer mag alleen bestaan uit nummers");
		}	else {
			addNewButton.setVisible(true);
			formGrid.setVisible(false);
			copyFieldDateToInschrijvenVak();
			this.inschrijvenVakService.addInschrijvenVak(currentInschrijvenVak);
		}
	}
	
	/** 
	 * In deze methode staat wat er moet gebeuren voordat op Updatebutton wordt
	 * geclickt voordat de ingevulde gegevens worden opgeslagen.
	 */

	public void gui_eventUpdateButtonClicked() {
		if	(studentNummerField.getText().length() == 0)
		{	Window.alert("Alle velden moeten gevuld zijn");
		}  else if (!studentNummerField.getText().matches("^[0-9]+$"))
		{	Window.alert("Studentnumer mag alleen bestaan uit nummers");
		}	else {
			addNewButton.setVisible(true);
			formGrid.setVisible(false);
			copyFieldDateToInschrijvenVak();
			this.inschrijvenVakService.updateInschrijvenVak(currentInschrijvenVak);
		}
	}
	
	/** 
	 * In deze methode staat wat er moet gebeuren voordat er op de
	 * knop AddnewButton wordt geklikt er wordt hier dus het formulier
	 * inschrijven vak getoont wat in de buildform wordt gemaakt
	 */

	public void gui_eventAddNewButtonClicked() {
		this.addNewButton.setVisible(false);
		this.updateButton.setVisible(false);
		this.addButton.setVisible(true);
		InschrijvenVak inschrijvenVak = new InschrijvenVak();
		inschrijvenVak.setVakNr(0L);
		loadForm(inschrijvenVak);
	}
	
	/** 
	 * Hier in staat het resultaat van de Arraylist
	 */

	public void service_vakkenListRetrievedFromService(List<Vak> result) {
		this.vakken = result;	
	}
	
	/** 
	 * In deze methode wordt de lijst getoont van de aanwezige Inschrijfvakken
	 */

	public void service_eventListRetrievedFromService(List<InschrijvenVak> result) {
		status.setText("Retrieved inschrijvenVak list");
		status.setVisible(true);

		//formGrid.setVisible(false);
		listGrid.setVisible(true);
		status.setVisible(true);
		addNewButton.setVisible(true);

		this.inschrijvenVakken = result;
		this.listGrid.clear();
		this.listGrid.resizeRows(this.inschrijvenVakken.size());
		int row = 0;
		this.addNewButton.setVisible(true);

		for (InschrijvenVak inschrijvenVak : result) {
			this.listGrid.setWidget(row, 0, new Label (inschrijvenVak.getStudentnummer()));
			if (vakken != null)
				for (Vak vak : vakken) {
					if (inschrijvenVak.getVakNr().longValue() == 
						vak.getVakNr().longValue()) {
						this.listGrid.setWidget(row, 1, new Label (vak.getCode()));
						this.listGrid.setWidget(row, 2, new Label (vak.getName()));
						this.listGrid.setWidget(row, EDIT_LINK, new Hyperlink("Edit", null));
						this.listGrid.setWidget(row, REMOVE_LINK, new Hyperlink("Remove", null));
						row ++;
					}
				}   
		}
	}
	
	/** 
	 * In deze methode wordt verteld of een inschrijven vak goed is toegevoegd
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */

	public void service_eventAddInschrijvenVakSuccessful() {
		status.setText("Inschrijving was successfully added");
		this.inschrijvenVakService.listInschrijvenVakken();
	}
	
	/** 
	 * In deze methode wordt verteld of een inschrijven vak goed is geupdated
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */

	public void service_eventUpdateSuccessful() {
		status.setText("Inschrijving was successfully updated");
		this.inschrijvenVakService.listInschrijvenVakken();
	}
	
	/** 
	 * In deze methode wordt verteld of een inschrijven vak goed is verwijderd
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */
	
	public void service_eventRemoveInschrijvenVakSuccessful() {
		status.setText("Inschrijving was removed");
		this.inschrijvenVakService.listInschrijvenVakken();
	}
	
	/** 
	 * In deze methode wordt verteld of een inschrijven vak niet goed is geupdated
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */

	public void service_eventUpdateInschrijvenVakFailed(Throwable caught) {
		status.setText("Update inschrijving failed");
	}
	
	/** 
	 * In deze methode wordt verteld of een inschrijven vak niet goed is toegevoegd
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */

	public void service_eventAddInschrijvenVakFailed(Throwable caught) {
		status.setText("Unable to update inschrijving");
	}
	
	/** 
	 * In deze methode wordt verteld of een inschrijven vak niet goed is verwijderd
	 * aan de database zo niet toont hij een status tekst met het resultaat
	 */

	public void service_eventRemoveInschrijvenVakFailed(Throwable caught) {
		status.setText("Remove inschrijving failed");
	}
	
	/** 
	 * In deze methode wordt verteld of een inschrijven vak niet goed wordt getoont
	 * in de lijst
	 */

	public void service_eventListInschrijvenVakkenFailed(Throwable caught) {
		status.setText("Unable to get inschrijving list");

	}

}
